package net.chrisjrock.display
{
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.MouseEvent;
	
	public class HotButtonController extends EventDispatcher
	{
		protected var displayAsset:MovieClip;
		protected var buttonEnabled:Boolean;
		
		protected var targetState:int = 1;
		protected var state:int = 1;
		
		protected var initComplete:Boolean;
		
		public function HotButtonController()
		{
			
		}
		
		public function destroyExternal ():void
		{
			removeListeners();
		}
		
		public function destroyInternal ():void
		{
			displayAsset = null;
		}
		
		public function init ():void
		{
			if (initComplete)
			{
				trace("HotButtonController: init: Cannot initialize more than once.");
				return;
			}
			
			if (!displayAsset)
			{
				trace("HotButtonController: init: Cannot initialize without a display asset.");
				return;
			}
			
			_setButtonEnabled(true);
			updateAsset();
			
			initComplete = true;
		}
		
		protected function addListeners ():void
		{
			if (!displayAsset)
			{
				return;
			}
			
			displayAsset.mouseEnabled = displayAsset.buttonMode = true;
			displayAsset.mouseChildren = false;
			
			displayAsset.addEventListener(MouseEvent.ROLL_OUT , rollOutHandler , false , 0 , true);
			displayAsset.addEventListener(MouseEvent.ROLL_OVER , rollOverHandler , false , 0 , true);
			displayAsset.addEventListener(MouseEvent.MOUSE_DOWN , mouseDownHandler , false , 0 , true);
			displayAsset.addEventListener(MouseEvent.MOUSE_UP , mouseUpHandler , false , 0 , true);
		}
		
		protected function removeListeners ():void
		{
			if (!displayAsset)
			{
				return;
			}
			
			displayAsset.mouseEnabled = displayAsset.buttonMode = false;
			
			displayAsset.removeEventListener(MouseEvent.ROLL_OUT , rollOutHandler);
			displayAsset.removeEventListener(MouseEvent.ROLL_OVER , rollOverHandler);
			displayAsset.removeEventListener(MouseEvent.MOUSE_DOWN , mouseDownHandler);
			displayAsset.removeEventListener(MouseEvent.MOUSE_UP , mouseUpHandler);
		}
		
		protected function _setButtonEnabled (value:Boolean):void
		{
			if (buttonEnabled != value)
			{
				buttonEnabled = value;
				
				if (buttonEnabled)
				{
					addListeners();
				}
				else
				{
					removeListeners();
				}
			}
		}
		
		protected function updateAsset ():void
		{
			if (!displayAsset)
			{
				targetState = this.state = 1;
				return;
			}
			
			var state:int = this.state;
			
			if (displayAsset.totalFrames >= targetState)
			{
				this.state = targetState;
			}
			else
			{
				this.state = targetState == 3 && displayAsset.totalFrames == 2 ? 2 : 1;
			}
			
			if (state != this.state)
			{
				displayAsset.gotoAndStop(this.state);
				dispatchEvent(new Event(Event.CHANGE));
			}
		}
		
		protected function rollOutHandler (event:MouseEvent):void
		{
			targetState = 1;
			updateAsset();
		}
		
		protected function rollOverHandler (event:MouseEvent):void
		{
			targetState = 2;
			updateAsset();
		}
		
		protected function mouseDownHandler (event:MouseEvent):void
		{
			targetState = 3;
			updateAsset();
		}
		
		protected function mouseUpHandler (event:MouseEvent):void
		{
			targetState = 2;
			updateAsset();
		}
		
		public function getDisplayAsset ():MovieClip
		{
			return displayAsset;
		}
		
		public function setDisplayAsset (value:MovieClip):void
		{
			if (initComplete)
			{
				trace("HotButtonController: setDislayAsset: Cannot set display asset after initiation is complete.");
				return;
			}
			
			displayAsset = value;
			
			if (displayAsset)
			{
				displayAsset.gotoAndStop(1);
			}
		}
		
		public function isButtonEnabled ():Boolean
		{
			return buttonEnabled;
		}
		
		public function setButtonEnabled (value:Boolean):void
		{
			if (!initComplete)
			{
				return;
			}
			
			_setButtonEnabled(value);
		}
		
		public function getTargetState():int
		{
			return targetState;
		}
		
		public function getState ():int
		{
			return state;
		}

	}
}